<template>
    <div class="wh-100% flex flex-col gap-2.5">
        <SearchCard
            :model="'admin'"
            @submit="(value: Partial<UserSearchDto>) => {searchConditions = value; handleRefresh()}"
            @reset="
                if (searchConditions !== null) {
                    searchConditions = null;
                    handleRefresh();
                }
            "
        />
        <n-card class="flex-1">
            <template #header>
                <div class="w-full flex justify-between">
                    <span>管理员列表</span>
                    <div class="flex gap-10px">
                        <n-button :focusable="false" @click="handleRefresh">
                            <template #icon>
                                <n-icon :component="Reload" />
                            </template>
                            刷新
                        </n-button>
                        <n-button
                            secondary
                            type="info"
                            :focusable="false"
                            @click="
                                userFormVisible = true;
                                userFormModel = 'create';
                                currentAdmin = null;
                            "
                        >
                            <template #icon>
                                <n-icon :component="Add" />
                            </template>
                            新建
                        </n-button>
                    </div>
                </div>
            </template>
            <div v-if="currentAdmins.length === 0" class="wh-100% flex-center">
                <n-result
                    status="418"
                    title="暂无数据"
                    description="一切尽在不言中"
                >
                </n-result>
            </div>
            <n-data-table
                v-else
                :columns="
                    adminColumns(
                        handleEditAdmin,
                        handleResetPassword,
                        handleDeleteAdmin
                    )
                "
                :data="currentAdmins"
                :row-key="(row: User) => row.id"
                :max-height="600"
            />
            <template #footer>
                <div class="w-full flex justify-between">
                    <span>共 {{ pagination.total }} 条</span>
                    <n-pagination
                        :total="pagination.total"
                        :page-size="pagination.size"
                        :page-count="
                            Math.ceil(pagination.total / pagination.size)
                        "
                        @update:page="handleChangePage"
                    />
                </div>
            </template>
        </n-card>
        <n-drawer v-model:show="userFormVisible" width="360">
            <n-drawer-content>
                <UserForm
                    :type="'admin'"
                    :model="userFormModel"
                    :data="currentAdmin"
                    @submit:data="handleSubmit"
                />
            </n-drawer-content>
        </n-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from "vue";

import { User } from "@/types/user";
import { NIcon } from "naive-ui";
import { Add, Reload } from "@vicons/ionicons5";

import { adminColumns } from "@/utils/table-column";
import { UserSearchDto, UserCreateDto } from "@/service/api/dto/user.dto";

import UserForm from "../components/user-form/index.vue";
import SearchCard from "../components/search-card/index.vue";

import {
    queryUsers,
    createUser,
    updateUser,
    deleteUser,
    resetPassword,
} from "@/service/api/user.ts";

const pagination = reactive({
    page: 1,
    size: 10,
    total: 0,
});

const userFormVisible = ref(false);
const userFormModel = ref<"create" | "update">("create");

const admins = new Map<number, User[]>();
const currentAdmin = ref<User | null>(null);
const currentAdmins = ref<User[]>([]);
const selectedAdmins = ref<User[]>([]);

const searchConditions = ref<Partial<UserSearchDto> | null>(null);

const handleQueryUsers = async () => {
    try {
        const res = await queryUsers(
            pagination.page,
            pagination.size,
            Object.assign(
                {
                    role: 1,
                },
                searchConditions.value
            )
        );
        pagination.total = res.count;
        admins.set(pagination.page, res.users);
        currentAdmins.value = res.users;
        pagination.page++;
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

onMounted(async () => {
    await handleQueryUsers();
});

const handleRefresh = async () => {
    pagination.page = 1;
    pagination.total = 0;
    admins.clear();
    currentAdmins.value = [];
    selectedAdmins.value = [];
    await handleQueryUsers();
};

const handleEditAdmin = (user: User) => {
    currentAdmin.value = user;
    userFormVisible.value = true;
    userFormModel.value = "update";
};

const handleResetPassword = (row: User) => {
    window.NDialog.info({
        title: "重置密码",
        content: "是否重置该用户密码",
        closable: false,
        positiveText: "确认",
        negativeText: "取消",
        onPositiveClick: async () => {
            await resetPassword(row.account, "abcd1234");
            window.NMessage.success("密码重置为'abcd1234'");
        },
    });
};

const handleSubmit = async (user: any) => {
    try {
        if (userFormModel.value === "create") {
            await createUser(user);
            window.NMessage.success("创建成功");
            userFormVisible.value = false;

            await handleRefresh();
        } else {
            let updateDto: Partial<User> = {
                account: currentAdmin.value?.account,
            };
            Object.keys(currentAdmin.value!).forEach((key) => {
                if (
                    currentAdmin.value![key as keyof User] !==
                    user[key as keyof User]
                ) {
                    currentAdmin.value![key as keyof User] =
                        user[key as keyof User];
                    updateDto[key as keyof User] = user[key as keyof User];
                }
            });
            if (Object.keys(updateDto).length === 0) {
                window.NMessage.warning("未修改任何内容");
                return;
            }
            await updateUser(updateDto);
            window.NMessage.success("修改成功");
        }
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

const handleDeleteAdmin = (user: User) => {
    window.NDialog.warning({
        title: "删除用户",
        content: "是否删除该用户",
        closable: false,
        positiveText: "确认",
        negativeText: "取消",
        onPositiveClick: async () => {
            try {
                await deleteUser(user.id);
                window.NMessage.success("删除成功");
                await handleRefresh();
            } catch (err) {
                window.NMessage.error((err as Error).message);
                return false;
            }
        },
    });
};

const handleChangePage = async (page: number) => {
    if (admins.has(page)) {
        currentAdmins.value = admins.get(page)!;
        return;
    }
    pagination.page = page;
    await handleQueryUsers();
};
</script>

<style scoped></style>
